---
<!-- title: Plugins -->
title: 插件
<!-- description: Extending Tailwind with reusable third-party plugins. -->
description: 使用可复用的第三方插件扩展 Tailwind。
---

import { Heading } from '@/components/Heading'
import { TipGood, TipBad } from '@/components/Tip'

## <Heading hidden>概述</Heading>

<!-- Plugins let you register new styles for Tailwind to inject into the user's stylesheet using JavaScript instead of CSS. -->
插件让您注册新的样式，让 Tailwind 使用 JavaScript 代替 CSS 注入用户的样式表。

<!-- To get started with your first plugin, import Tailwind's `plugin` function from `tailwindcss/plugin`. Then inside your `plugins` array, and call it with an anonymous function as the first argument. -->
要开始您的第一个插件，先从 `tailwindcss/plugin` 导入 Tailwind 的 `plugin` 函数。然后在您的 `plugins` 数组中，调用这个函数，用一个匿名函数作为其第一个参数。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities, addComponents, e, prefix, config }) {
      // Add your custom styles here
    }),
  ]
}
```

<!-- Plugin functions receive a single object argument that can be [destructured](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) into several helper functions: -->
插件函数接收一个单一的对象参数，可以 [destructured](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) 成几个帮助函数。

- `addUtilities()`, for registering new utility styles
- `addComponents()`, for registering new component styles
- `addBase()`, for registering new base styles
- `addVariant()`, for registering custom variants
- `e()`, for escaping strings meant to be used in class names
- `prefix()`, for manually applying the user's configured prefix to parts of a selector
- `theme()`, for looking up values in the user's theme configuration
- `variants()`, for looking up values in the user's variants configuration
- `config()`, for looking up values in the user's Tailwind configuration
- `postcss`, for doing low-level manipulation with [PostCSS](https://api.postcss.org/postcss.html) directly

---

<!-- ## Adding utilities -->
## 添加功能类

<!-- The `addUtilities` function allows you to register new styles in Tailwind's `utilities` layer. -->
`addUtilities` 函数允许您在 Tailwind 的 `utilities` 层注册新的样式。

<!-- Plugin utilities are output in the order they are registered, *after* built-in utilities, so if a plugin targets any of the same properties as a built-in utility, the plugin utility will take precedence. -->
插件功能类的输出顺序是按照其注册的顺序，在内置的功能类*之后*，所以如果一个插件的作用目标是任何一个与内置功能类相同的属性，插件功能类将优先。

<!-- To add new utilities from a plugin, call `addUtilities`, passing in your styles using [CSS-in-JS syntax](#css-in-js-syntax): -->
要从插件中添加新的功能类，调用 `addUtilities`，使用 [CSS-in-JS 语法](#css-in-js) 传递您的样式。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        '.skew-10deg': {
          transform: 'skewY(-10deg)',
        },
        '.skew-15deg': {
          transform: 'skewY(-15deg)',
        },
      }

      addUtilities(newUtilities)
    })
  ]
}
```

<!-- ### Prefix and important preferences -->
### 前缀 和 important 参考

<!-- By default, plugin utilities automatically respect the user's [`prefix`](/docs/configuration/#prefix) and [`important`](/docs/configuration/#important) preferences. -->
默认情况下，插件功能类会自动遵守用户的 [`prefix`](/docs/configuration/#prefix) 和 [`important`](/docs/configuration/#important) 偏好。

<!-- That means that given this Tailwind configuration: -->
也就是说，如果给出这样的 Tailwind 配置：

```js
// tailwind.config.js
module.exports = {
  prefix: 'tw-',
  important: true,
  // ...
}
```

<!-- ...the example plugin above would generate the following CSS: -->
...上面的示例插件会生成以下CSS:

```css
.tw-skew-10deg {
  transform: skewY(-10deg) !important;
}
.tw-skew-15deg {
  transform: skewY(-15deg) !important;
}
```

<!-- If necessary, you can opt out of this behavior by passing an options object as a second parameter to `addUtilities`: -->
如果有必要，您可以通过向 `addUtilities` 传递一个选项对象作为第二个参数来选择不使用这种行为。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, {
        respectPrefix: false,
        respectImportant: false,
      })
    })
  ]
}
```

<!-- ### Variants -->
### 变体

<!-- To generate responsive, hover, focus, active, or other variants of your styles, specify the variants you'd like to generate using the `variants` option: -->
要生成 responsive、hover、focus、active 或样式的其它变体，请使用 `variants` 选项指定您想生成的变体。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, {
        variants: ['responsive', 'hover'],
      })
    })
  ]
}
```

<!-- If you only need to specify variants and don't need to opt-out of the default prefix or important options, you can also pass the array of variants as the second parameter directly: -->
如果您只需要指定变体，而不需要选择不使用默认的前缀或 important 选项，您也可以直接将变体数组作为第二个参数传递。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, ['responsive', 'hover'])
    })
  ]
}
```

<!-- If you'd like the user to provide the variants themselves under the `variants` section in their `tailwind.config.js` file, you can use the `variants()` function to get the variants they have configured: -->
如果您希望用户在他们的 `tailwind.config.js` 文件中的 `variants` 部分提供自己的变体，您可以使用 `variants()` 函数来获取他们配置的变体。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  variants: {
    customPlugin: ['responsive', 'hover'],
  },
  plugins: [
    plugin(function({ addUtilities, variants }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, variants('customPlugin'))
    })
  ]
}
```

---

<!-- ## Adding components -->
## 增加组件

<!-- The `addComponents` function allows you to register new styles in Tailwind's `components` layer. -->
`addComponents` 函数允许您在 Tailwind 的 `components` 层注册新的样式。

<!-- Use it to add more opinionated, complex classes like buttons, form controls, alerts, etc; the sort of pre-built components you often see in other frameworks that you might need to override with utility classes. -->
用它来添加更个性化、更复杂的类，比如按钮、表单控件、警告等；就是您在其他框架中经常看到的您可能需要使用功能类覆盖的那种预建组件。

<!-- To add new component styles from a plugin, call `addComponents`, passing in your styles using [CSS-in-JS syntax](#css-in-js-syntax): -->
要从插件中添加新的组件样式，调用 `addComponents` ，使用 [CSS-in-JS 语法](#css-in-js-syntax) 传递您的样式。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const buttons = {
        '.btn': {
          padding: '.5rem 1rem',
          borderRadius: '.25rem',
          fontWeight: '600',
        },
        '.btn-blue': {
          backgroundColor: '#3490dc',
          color: '#fff',
          '&:hover': {
            backgroundColor: '#2779bd'
          },
        },
        '.btn-red': {
          backgroundColor: '#e3342f',
          color: '#fff',
          '&:hover': {
            backgroundColor: '#cc1f1a'
          },
        },
      }

      addComponents(buttons)
    })
  ]
}
```

<!-- ### Prefix and important preferences -->
### 前缀 和 important 参考

<!-- By default, component classes automatically respect the user's `prefix` preference, but **they are not affected** by the user's `important` preference. -->
默认情况下，组件类自动遵守用户的 `prefix` 偏好，但**不受用户的 `important` 偏好的影响**。

<!-- That means that given this Tailwind configuration: -->
这意味着如果有以下 Tailwind 配置：

```js
// tailwind.config.js
module.exports = {
  prefix: 'tw-',
  important: true,
  // ...
}
```

<!-- ...the example plugin above would generate the following CSS: -->
...上面的示例插件将生成以下 CSS:

```css
.tw-btn {
  padding: .5rem 1rem;
  border-radius: .25rem;
  font-weight: 600;
}
.tw-btn-blue {
  background-color: #3490dc;
  color: #fff;
}
.tw-btn-blue:hover {
  background-color: #2779bd;
}
.tw-btn-blue {
  background-color: #e3342f;
  color: #fff;
}
.tw-btn-blue:hover {
  background-color: #cc1f1a;
}
```

<!-- Although there's rarely a good reason to make component declarations important, if you really need to do it you can always add `!important` manually: -->
虽然很少有一个很好的理由让组件声明 important，但如果您真的需要这样做，您可以手动添加 `!important` 。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const buttons = {
        '.btn': {
          padding: '.5rem 1rem !important',
          borderRadius: '.25rem !important',
          fontWeight: '600 !important',
        },
        // ...
      }

      addComponents(buttons)
    })
  ]
}
```

<!-- All classes in a selector will be prefixed by default, so if you add a more complex style like: -->
选择器中的所有类都会默认添加前缀，所以如果您添加一个更复杂的样式，比如：

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  prefix: 'tw-',
  plugins: [
    plugin(function({ addComponents }) {
      const components = {
        // ...
        '.navbar-inverse a.nav-link': {
            color: '#fff',
        }
      }

      addComponents(components)
    })
  ]
}
```

<!-- ...the following CSS would be generated: -->
...将生成以下的 CSS:

```css
.tw-navbar-inverse a.tw-nav-link {
    color: #fff;
}
```

<!-- To opt out of prefixing, pass an options object as a second parameter to `addComponents`: -->
要选择不使用前缀，可以传递一个 options 对象作为第二个参数给 `addComponents`：

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  prefix: 'tw-',
  plugins: [
    plugin(function({ addComponents }) {
      const components = {
        // ...
      }

      addComponents(components, {
        respectPrefix: false
      })
    })
  ]
}
```

<!-- ### Variants -->
### 变体

<!-- To generate responsive, hover, focus, active, or other variants of your components, specify the variants you'd like to generate using the `variants` option: -->
要生成组件的 responsive、hover、focus、active或其他变体，请使用 `variants` 选项指定您想生成的变体。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const newComponents = {
        // ...
      }

      addComponents(newComponents, {
        variants: ['responsive', 'hover'],
      })
    })
  ]
}
```

<!-- If you only need to specify variants and don't need to opt-out of the default prefix or important options, you can also pass the array of variants as the second parameter directly: -->
如果您只需要指定变体，而不需要选择不使用默认的前缀或 important 选项，您也可以直接将变体数组作为第二个参数传递。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const newComponents = {
        // ...
      }

      addComponents(newComponents, ['responsive', 'hover'])
    })
  ]
}
```

<!-- If you'd like the user to provide the variants themselves under the `variants` section in their `tailwind.config.js` file, you can use the `variants()` function to get the variants they have configured: -->
如果您希望用户在他们的 `tailwind.config.js` 文件中的 `variants` 部分提供自己的变体，您可以使用 `variants()` 函数来获取他们配置的变体。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  variants: {
    customPlugin: ['responsive', 'hover'],
  },
  plugins: [
    plugin(function({ addComponents, variants }) {
      const newComponents = {
        // ...
      }

      addComponents(newComponents, variants('customPlugin'))
    })
  ]
}
```

---

<!-- ## Adding base styles -->
## 添加基础样式

<!-- The `addBase` function allows you to register new styles in Tailwind's `base` layer. -->
`addBase` 函数允许您在 Tailwind 的 `base` 层注册新的样式。

<!-- Use it to add things like base typography styles, opinionated global resets, or `@font-face` rules. -->
使用它来添加诸如基本的排版样式、个性化的全局重置或 `@font-face` 规则。

<!-- To add new base styles from a plugin, call `addBase`, passing in your styles using [CSS-in-JS syntax](#css-in-js-syntax): -->
要从插件中添加新的基础样式，调用 `addBase`，使用 [CSS-in-JS 语法](#css-in-js-syntax) 传递您的样式。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addBase, config }) {
      addBase({
        'h1': { fontSize: config('theme.fontSize.2xl') },
        'h2': { fontSize: config('theme.fontSize.xl') },
        'h3': { fontSize: config('theme.fontSize.lg') },
      })
    })
  ]
}
```

<!-- Since base styles are meant to target bare selectors like `div`, `h1`, etc., they do not respect the user's `prefix` or `important` configuration. -->
由于基本样式是针对 `div`、`h1` 等裸选择器的，所以它们不遵从用户的 `prefix` 或 `important` 配置。

---

<!-- ## Escaping class names -->
## 转义类名

<!-- If your plugin generates classes that contain user-provided strings, you can use the `e` function to escape those class names to make sure non-standard characters are handled properly automatically. -->
如果您的插件生成的类中包含用户提供的字符串，您可以使用 `e` 函数来转义这些类名，以确保非标准字符被正确地自动处理。

<!-- For example, this plugin generates a set of `.rotate-{angle}` utilities where `{angle}` is a user provided string. The `e` function is used to escape the concatenated class name to make sure classes like `.rotate-1/4` work as expected: -->
例如，这个插件生成了一组 `.rotate-{angle}` 功能类，其中 `{angle}` 是用户提供的字符串。`e` 函数用于转义连接的类名，以确保像 `.rotate-1/4` 这样的类能按预期工作。


```js
// tailwind.config.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = {
  theme: {
    rotate: {
      '1/4': '90deg',
      '1/2': '180deg',
      '3/4': '270deg',
    }
  },
  plugins: [
    plugin(function({ addUtilities, config, e }) {
      const rotateUtilities = _.map(config('theme.rotate'), (value, key) => {
        return {
          [`.${e(`rotate-${key}`)}`]: {
            transform: `rotate(${value})`
          }
        }
      })

      addUtilities(rotateUtilities)
    })
  ]
}
```

<!-- This plugin would generate the following CSS: -->
这个插件会生成以下CSS：

```css
.rotate-1\/4 {
  transform: rotate(90deg);
}
.rotate-1\/2 {
  transform: rotate(180deg);
}
.rotate-3\/4 {
  transform: rotate(270deg);
}
```

<!-- Be careful to only escape content you actually want to escape; don't pass the leading `.` in a class name or the `:` at the beginning pseudo-classes like `:hover` or `:focus` or those characters will be escaped. -->
注意只转义您真正想转义的内容；不要在类名中传递前导的 `.` 或在 `:hover` 或 `:focus` 等伪类的开头传递 `:`，否则这些字符将被转义。

<!-- Additionally, because CSS has rules about the characters a class name can *start* with (a class can't start with a number, but it can contain one), it's a good idea to escape your complete class name (not just the user-provided portion) or you may end up with unnecessary escape sequences: -->
此外，因为 CSS 有关于类名的规则（类名不能以数字开头，但可以包含数字），所以最好是转义完整的类名（不只是用户提供的部分），否则您可能会得到不必要的转义序列。

```js
// Will unnecessarily escape `1`
`.rotate-${e('1/4')}`
// => '.rotate-\31 \/4'

// Won't escape `1` because it's not the first character
`.${e('rotate-1/4')}`
// => '.rotate-1\/4'
```

---

<!-- ## Manually prefixing selectors -->
## 手动给选择器加前缀

<!-- If you're writing something complex where you only want to prefix certain classes, you can use the `prefix` function to have fine-grained control of when the user's configured prefix is applied. -->
如果您正在写一些复杂的东西，您只想给某些类加前缀，您可以使用 `prefix` 函数来精细控制何时应用用户配置的前缀。

<!-- For example, if you're creating a plugin to be reused across a set of internal projects that includes existing classes in its selectors, you might only want to prefix the new classes: -->
例如，如果您正在创建一个插件，以便在一组内部项目中重复使用，在其选择器中包含现有的类，您可能只想给新的类加上前缀。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  prefix: 'tw-',
  plugins: [
    plugin(function({ addComponents, prefix }) {
      addComponents({
        [`.existing-class > ${prefix('.new-class')}`]: {
          backgroundColor: '#fff',
        }
      })
    })
  ]
}
```

<!-- This would generate the following CSS: -->
这将生成以下CSS：

```css
.existing-class > .tw-new-class {
  background-color: #fff;
}
```

<!-- The `prefix` function will prefix all classes in a selector and ignore non-classes, so it's totally safe to pass complex selectors like this one: -->
`prefix` 函数会给选择器中的所有类加前缀，而忽略不是类的选择器，所以传递像这样复杂的选择器是完全安全的。

```js
prefix('.btn-blue .w-1\/4 > h1.text-xl + a .bar')
// => '.tw-btn-blue .tw-w-1\/4 > h1.tw-text-xl + a .tw-bar'
```

---

<!-- ## Referencing the user's config -->
## 引用用户配置

<!-- The `config`, `theme`, and `variants` functions allow you to ask for a value from the user's Tailwind configuration using dot notation, providing a default value if that path doesn't exist. -->
`config`、`theme` 和 `variants` 函数允许您使用点符号从用户的 Tailwind 配置中获取一个值，如果该路径不存在，则提供一个默认值。

<!-- For example, this simplified version of the built-in [container](/docs/container) plugin uses the `theme` function to get the user's configured breakpoints: -->
例如，这个简化版的内置 [容器](/docs/container) 插件使用 `theme` 函数来获取用户配置的断点。

```js
// tailwind.config.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents, theme }) {
      const screens = theme('screens', {})

      const mediaQueries = _.map(screens, width => {
        return {
          [`@media (min-width: ${width})`]: {
            '.container': {
              'max-width': width,
            },
          },
        }
      })

      addComponents([
        { '.container': { width: '100%' } },
        ...mediaQueries,
      ])
    })
  ]
}
```

<!-- Note that the `theme` function is really just a shortcut for using the `config` function to access the theme section of the user's config: -->
请注意，`theme` 函数实际上只是使用 `config` 函数访问用户配置的主题部分的一个快捷方式。

```js
// These are equivalent
config('theme.screens')
theme('screens')
```

<!-- If you'd like to reference the user's `variants` configuration, it's recommended that you use the `variants()` function instead of the config function. -->
如果您想引用用户的 `variants` 配置，建议您使用 `variants()` 函数而不是 config 函数。

<!-- <TipBad>Don't use the config function to look up variants</TipBad> -->
<TipBad>不要使用 config 函数来查找变体</TipBad>

```js
addUtilities(newUtilities, config('variants.customPlugin'))
```

<!-- <TipGood>Use the variants function instead</TipGood> -->
<TipGood>使用 variants 函数代替</TipGood>

```js
addUtilities(newUtilities, variants('customPlugin'))
```

<!-- Since `variants` could simply be a global list of variants to configure for every plugin in the whole project, using the `variants()` function lets you easily respect the user's configuration without reimplementing that logic yourself. -->
由于 `variants` 可以简单地成为一个全局的变体列表，为整个项目中的每一个插件进行配置，所以使用 `variants()` 函数可以让您很容易地遵从用户的配置，而不是自己重新实现这个逻辑。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  variants: ['responsive', 'hover', 'focus'],
  plugins: [
    plugin(function ({ config, variants }) {
      config('variants.customPlugin')
      // => undefined

      variants('customPlugin')
      // => ['reponsive', 'hover', 'focus']
    })
  ]
}
```

---

<!-- ## Exposing options -->
## 暴露选项

<!-- It often makes sense for a plugin to expose its own options that the user can configure to customize the plugin's behavior. -->
通常情况下，一个插件暴露自己的选项是有意义的，用户可以配置这些选项来定制插件的行为。

<!-- The best way to accomplish this is to claim your own key in the user's `theme` and `variants` configuration and ask them to provide any options there so you can access them with the `theme` and `variants` functions. -->
最好的方法是在用户的 `theme` 和 `variants` 配置中定义自己的键，并要求他们在那里提供任何选项，这样您就可以通过 `theme` 和 `variants` 函数访问它们。

<!-- For example, here's a plugin *(extracted to its own module)* for creating simple gradient utilities that accepts the gradients and variants to generate as options: -->
例如，这里有一个插件*(提取到自己的模块)*，用于创建简单的渐变功能类，接受要生成的渐变值和变体做为选项。

```js
// ./plugins/gradients.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = plugin(function({ addUtilities, e, theme, variants }) {
  const gradients = theme('gradients', {})
  const gradientVariants = variants('gradients', [])

  const utilities = _.map(gradients, ([start, end], name) => ({
    [`.${e(`bg-gradient-${name}`)}`]: {
      backgroundImage: `linear-gradient(to right, ${start}, ${end})`
    }
  }))

  addUtilities(utilities, gradientVariants)
})
```

<!-- To use it, you'd `require` it in your plugins list, specifying your configuration under the `gradients` key in both `theme` and `variants`: -->
要使用它，您需要在您的插件列表中 `require` 它，在 `theme` 和 `variants` 中的 `gradients` 键下指定您的配置。

```js
// tailwind.config.js
module.exports = {
  theme: {
    gradients: theme => ({
      'blue-green': [theme('colors.blue.500'), theme('colors.green.500')],
      'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')],
      // ...
    })
  },
  variants: {
    gradients: ['responsive', 'hover'],
  },
  plugins: [
    require('./plugins/gradients')
  ],
}
```

<!-- ### Providing default options -->
### 提供默认选项

<!-- To provide default `theme` and `variants` options for your plugin, pass a second argument to Tailwind's `plugin` function that includes your defaults: -->
要为您的插件提供默认的 `theme` 和 `variants` 选项，请向 Tailwind 的 `plugin` 函数传递包含默认值的第二个参数，。

```js
// ./plugins/gradients.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = plugin(function({ addUtilities, e, theme, variants }) {
  // ...
}, {
  theme: {
    gradients: theme => ({
      'blue-green': [theme('colors.blue.500'), theme('colors.green.500')],
      'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')],
      // ...
    })
  },
  variants: {
    gradients: ['responsive', 'hover'],
  }
})
```

<!-- This object is just another [Tailwind configuration object](/docs/configuration) and has all of the same properties and features as the config object you're used to working with in `tailwind.config.js`. -->
这个对象只是另一个 [Tailwind 配置对象](/docs/configuration)，并具有与 `tailwind.config.js` 中使用的配置对象相同的所有属性和功能。

<!-- By providing your defaults this way, end users will be able to [override](/docs/theme#overriding-the-default-theme) and [extend](/docs/theme#extending-the-default-theme) your defaults the same way they can with Tailwind's built-in styles. -->
通过以这种方式提供您的默认值，最终用户将能够 [覆盖](/docs/theme#overriding-the-default-theme) 和 [扩展](/docs/theme#extending-the-default-theme) 您的默认值，就像他们可以覆盖和扩展 Tailwind 的内置样式一样。

---

<!-- ## CSS-in-JS syntax -->
## CSS-in-JS 语法

<!-- Each of `addUtilities`, `addComponents`, and `addBase` expect CSS rules written as JavaScript objects. Tailwind uses the same sort of syntax you might recognize from CSS-in-JS libraries like [Emotion](https://emotion.sh/docs/object-styles), and is powered by [postcss-js](https://github.com/postcss/postcss-js) under the hood. -->
每一个 `addUtilities`、`addComponents` 和 `addBase` 都期望 CSS 规则写成 JavaScript 对象。Tailwind 使用的语法，您可能会从 CSS-in-JS 库中识别出来，如 [Emotion](https://emotion.sh/docs/object-styles)，并由 [postcss-js](https://github.com/postcss/postcss-js) 提供支持。

<!-- Consider this simple CSS rule: -->
考虑这个简单的CSS规则：

```css
.card {
  background-color: #fff;
  border-radius: .25rem;
  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
```

<!-- Translating this to a CSS-in-JS object would look like this: -->
将其翻译成 CSS-in-JS 对象，就像这样：

```js
addComponents({
  '.card': {
    'background-color': '#fff',
    'border-radius': '.25rem',
    'box-shadow': '0 2px 4px rgba(0,0,0,0.2)',
  }
})
```

<!-- For convenience, property names can also be written in camelCase and will be automatically translated to dash-case: -->
为方便起见，属性名也可以用 camelCase 书写，并会自动翻译成 dash-case：

```js
addComponents({
  '.card': {
    backgroundColor: '#fff',
    borderRadius: '.25rem',
    boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
  }
})
```

<!-- Nesting is also supported (powered by [postcss-nested](https://github.com/postcss/postcss-nested)), using the same syntax you might be familiar with from Sass or Less: -->
也支持嵌套（由 [postcss-nested](https://github.com/postcss/postcss-nested) 提供支持），使用您可能熟悉的 Sass 或 Less 的相同语法。

```js
addComponents({
  '.card': {
    backgroundColor: '#fff',
    borderRadius: '.25rem',
    boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
    '&:hover': {
      boxShadow: '0 10px 15px rgba(0,0,0,0.2)',
    },
    '@media (min-width: 500px)': {
      borderRadius: '.5rem',
    }
  }
})
```

<!-- Multiple rules can be defined in the same object: -->
同一对象中可以定义多个规则：

```js
addComponents({
  '.btn': {
    padding: '.5rem 1rem',
    borderRadius: '.25rem',
    fontWeight: '600',
  },
  '.btn-blue': {
    backgroundColor: '#3490dc',
    color: '#fff',
    '&:hover': {
      backgroundColor: '#2779bd'
    },
  },
  '.btn-red': {
    backgroundColor: '#e3342f',
    color: '#fff',
    '&:hover': {
      backgroundColor: '#cc1f1a'
    },
  },
})
```

<!-- ...or as an array of objects in case you need to repeat the same key: -->
...或者作为一个对象数组，以备您需要重复使用同一个键：

```js
addComponents([
  {
    '@media (min-width: 500px)': {
      // ...
    }
  },
  {
    '@media (min-width: 500px)': {
      // ...
    }
  },
  {
    '@media (min-width: 500px)': {
      // ...
    }
  },
])
```

---

## Adding variants
## 增加变体

<!-- The `addVariant` function allows you to register your own custom [variants](/docs/hover-focus-and-other-states) that can be used just like the built-in hover, focus, active, etc. variants. -->
`addVariant` 函数允许您注册自己的自定义 [变体](/docs/hover-focus-andother-states)，这些变体可以像内置的 hover、hover、hover 等变体一样使用。

<!-- To add a new variant, call the `addVariant` function, passing in the name of your custom variant, and a callback that modifies the affected CSS rules as needed. -->
要添加一个新的变量，调用 `addVariant` 函数，传入您的自定义变量的名称，以及一个回调，根据需要修改受影响的 CSS 规则。

```js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e }) {
      addVariant('disabled', ({ modifySelectors, separator }) => {
        modifySelectors(({ className }) => {
          return `.${e(`disabled${separator}${className}`)}:disabled`
        })
      })
    })
  ]
}
```

<!-- The callback receives an object that can be destructured into the following parts: -->
回调收到的对象可以被反构为以下部分：

- `modifySelectors`, a helper function to simplify adding basic variants
- `separator`, the user's configured [separator string](/docs/configuration#separator)
- `container`, a [PostCSS Container](http://api.postcss.org/Container.html) containing all of the rules the variant is being applied to, for creating complex variants

### Basic variants
### 基本变体

<!-- If you want to add a simple variant that only needs to change the selector, use the `modifySelectors` helper. -->
如果您想添加一个简单的变量，只需要改变选择器，使用 `modifySelectors` 助手。

<!-- The `modifySelectors` helper accepts a function that receives an object that can be destructured into the following parts: -->
`modifySelectors` 助手接受一个函数，该函数接收一个对象，该对象可以被重构为以下部分：

- `selector`, the complete unmodified selector for the current rule
- `className`, the class name of the current rule *with the leading dot removed*

<!-- The function you pass to `modifySelectors` should simply return the modified selector. -->
您传递给 `modifySelectors` 的函数应该简单地返回修改后的选择器。

<!-- For example, a `first-child` variant plugin could be written like this: -->
例如，一个 `first-child` 的变体插件可以这样写：

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e }) {
      addVariant('first-child', ({ modifySelectors, separator }) => {
        modifySelectors(({ className }) => {
          return `.${e(`first-child${separator}${className}`)}:first-child`
        })
      })
    })
  ]
}
```

<!-- ### Complex variants -->
### 复杂变体

<!-- If you need to do anything beyond simply modifying selectors (like changing the actual rule declarations, or wrapping the rules in another at-rule), you'll need to use the `container` instance. -->
如果您需要做的事情不仅仅是简单地修改选择器（比如改变实际的规则声明，或者将规则包装在另一个 at-rule 中），您将需要使用 `container` 实例。

<!-- Using the `container` instance, you can traverse all of the rules within a given module or `@variants` block and manipulate them however you like using the standard PostCSS API. -->
使用 `container` 实例，您可以在给定的模块或 `@variants` 块中遍历所有的规则，并使用标准的 PostCSS API 随意操作它们。

<!-- For example, this plugin creates an `important` version of each affected utility by prepending the class with an exclamation mark and modifying each declaration to be `important`: -->
例如，该插件通过在类前加上感叹号，并将每个声明修改为 `important`，为每个受影响的功能创建一个 `important` 版本。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant }) {
      addVariant('important', ({ container }) => {
        container.walkRules(rule => {
          rule.selector = `.\\!${rule.selector.slice(1)}`
          rule.walkDecls(decl => {
            decl.important = true
          })
        })
      })
    })
  ]
}
```

<!-- This plugin takes all of the rules inside the container, wraps them in a `@supports (display: grid)` at-rule, and prefixes each rule with `supports-grid`: -->
这个插件将容器内的所有规则，用 `@supports (display: grid)` at-rule 包装起来，并在每个规则前加上 `supports-grid` 。

```js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e, postcss }) {
      addVariant('supports-grid', ({ container, separator }) => {
        const supportsRule = postcss.atRule({ name: 'supports', params: '(display: grid)' })
        supportsRule.append(container.nodes)
        container.append(supportsRule)
        supportsRule.walkRules(rule => {
          rule.selector = `.${e(`supports-grid${separator}${rule.selector.slice(1)}`)}`
        })
      })
    })
  ]
}
```

<!-- To learn more about working with PostCSS directly, check out the [PostCSS API documentation](http://api.postcss.org/Container.html). -->
要了解更多关于直接使用 PostCSS 的信息，请查看 [PostCSS API 文档](http://api.postcss.org/Container.html)。

### Using custom variants
### 使用自定义变体

<!-- Using custom variants is no different than using Tailwind's built-in variants. -->
使用自定义变体与使用 Tailwind 的内置变体没有什么不同。

<!-- To use custom variants with Tailwind's core plugins, add them to the `variants` section of your config file: -->
要使定制的变体与 Tailwind 的核心插件一起使用，将它们添加到您的配置文件的 `variants` 部分。

```js
// tailwind.config.js
modules.exports = {
  variants: {
    borderWidths: ['responsive', 'hover', 'focus', 'first-child', 'disabled'],
  }
}
```

<!-- To use custom variants with custom utilities in your own CSS, use the [variants at-rule](/docs/functions-and-directives#variants): -->
要在您自己的CSS中使自定义变体和自定义功能类一起使用，请使用 [variants at-rule](/docs/functions-and-directives#variants)。

```css
@variants hover, first-child {
  .bg-cover-image {
    background-image: url('/path/to/image.jpg');
  }
}
```
